package com.cjd.view;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

import androidx.annotation.Nullable;

import com.cjd.common.R;


/**
 * @Author chenjidong
 * @email 374122600@qq.com
 * created 2018/3/16
 * description 电池进度
 */

public class BatteryProgressView extends View {
    private int power = 20;
    /**
     * 具体看 {@link android.os.BatteryManager#BATTERY_PLUGGED_AC}
     */
    private int plugged = -1;//连接usb 或 充电头

    //手机密度
    float density;
    //电池线 电池头 电池内部 剩余电量 文字
    private Paint batteryLinePaint, batteryHeadPaint, batteryInsidePaint, batteryRemainingPowerPaint, batteryScaleTextPaint;

    private int batteryColor, batteryLineColor, batteryRemainingColor;

    //电池宽度 不包含左右两边的边距 和边线
    private float powerWidth, powerHeight, batteryLineWidth, insideMargin, batteryHeadWidth, batteryHeadHeight;

    private Bitmap pluggedBitmap;

    // view 的宽高
    private int viewWidth, viewHeight;
    //电池剩余电量透明度
    private int batteryRemainingAlpha;

    private int segmentNum = 5;//电池分段数量
    //当前电池分段数 、剩余分段数
    private int segmentCurrentCount, segmentRemainingCount;
    //分段数 width
    private float segmentWidth;
    //电池实际高度
    private float power_left, power_top, power_bottom, power_right;

    private boolean isPlugEnabled, isTextScaleEnabled, isRemainingPowerEnabled = true;
    private ValueAnimator remainingAlphaAnimator;

    private float outsideRound = 5, powerRound = 5;//分段圆角  包括电池头 和外框边线

    private RectF batteryOutsideBorderRectF, segmentRectF;//电池最外框 电量分段

    private String text;

    private int animationType = 1;// 0 普通渐变 1 根据剩余电量块 渐变
    private int duration = 3000;

    public BatteryProgressView(Context context) {
        this(context, null);

    }

    public BatteryProgressView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
        initView(context, attrs);
    }

    public BatteryProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs);
    }

    private void initView(Context context, AttributeSet attrs) {
        batteryOutsideBorderRectF = new RectF();
        segmentRectF = new RectF();

        density = getResources().getDisplayMetrics().density;
        int defaultColor = Color.WHITE;
        if (attrs != null) {
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BatteryProgressView);
            batteryColor = ta.getColor(R.styleable.BatteryProgressView_battery_color, defaultColor);
            batteryRemainingColor = ta.getColor(R.styleable.BatteryProgressView_battery_remaining_color, defaultColor);
            batteryLineColor = batteryColor;//外框线颜色 和电量颜色一致

            batteryLineWidth = ta.getDimension(R.styleable.BatteryProgressView_battery_line_width, dp2px(2));
            insideMargin = ta.getDimension(R.styleable.BatteryProgressView_battery_inside_margin, dp2px(5));

            outsideRound = ta.getDimension(R.styleable.BatteryProgressView_battery_outside_round, dp2px(2));
            powerRound = ta.getDimension(R.styleable.BatteryProgressView_battery_power_round, dp2px(2));
            ta.recycle();
        }

        if (batteryLineWidth == 0)
            batteryLineWidth = dp2px(2);

        batteryLinePaint = new Paint();
        batteryLinePaint.setColor(batteryLineColor == 0 ? defaultColor : batteryLineColor);
        batteryLinePaint.setStyle(Paint.Style.STROKE);
        batteryLinePaint.setStrokeWidth(batteryLineWidth);

        batteryHeadPaint = new Paint(batteryLinePaint);
        batteryHeadPaint.setStyle(Paint.Style.FILL);

        batteryInsidePaint = new Paint();
        batteryInsidePaint.setColor(batteryColor == 0 ? defaultColor : batteryColor);
        batteryInsidePaint.setStyle(Paint.Style.FILL);

        batteryScaleTextPaint = new Paint(batteryLinePaint);
        batteryScaleTextPaint.setStyle(Paint.Style.FILL);
        batteryScaleTextPaint.setColor(Color.WHITE);
        batteryScaleTextPaint.setTextSize(dp2px(25));
        batteryScaleTextPaint.setStrokeWidth(1);
        batteryScaleTextPaint.setTextAlign(Paint.Align.CENTER);//基线剧中

        batteryRemainingPowerPaint = new Paint(batteryInsidePaint);
        batteryRemainingPowerPaint.setStyle(Paint.Style.FILL);
        batteryRemainingPowerPaint.setColor(batteryRemainingColor == 0 ? defaultColor : batteryRemainingColor);

        remainingAlphaAnimator = ValueAnimator.ofInt(0, 255);
        remainingAlphaAnimator.setRepeatCount(ValueAnimator.INFINITE);
        remainingAlphaAnimator.setInterpolator(new DecelerateInterpolator());
        remainingAlphaAnimator.setDuration(duration);
        remainingAlphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                batteryRemainingAlpha = (int) animation.getAnimatedValue();
                invalidate();
            }
        });
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED) {
            viewWidth = MeasureSpec.getSize(widthMeasureSpec);
        } else
            viewWidth = getResources().getDisplayMetrics().widthPixels;

        if (MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.UNSPECIFIED) {
            viewHeight = MeasureSpec.getSize(heightMeasureSpec);
        } else
            viewHeight = viewWidth > 0 ? viewWidth / 4 : dp2px(100);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        setPadding(10, 10, 10, 10);
        //电量
        powerWidth = viewWidth - batteryHeadWidth - insideMargin * 2
                - batteryLineWidth * 2 - getPluggedWidth();

        powerHeight = viewHeight - insideMargin * 2 - batteryLineWidth * 2;
        batteryHeadHeight = powerHeight / 4;
        batteryHeadWidth = batteryLineWidth * 3;

        float battery_right = powerWidth + insideMargin * 2 + batteryLineWidth * 2;
        float battery_left = (viewWidth - battery_right - batteryHeadWidth - getPluggedWidth()) / 2 + batteryLineWidth;
        float battery_top = viewHeight - powerHeight - insideMargin * 2 - batteryLineWidth;
        float battery_bottom = battery_top + powerHeight;

        //先画外框 不包含 电池头
        batteryOutsideBorderRectF.set(battery_left, battery_top, battery_right, battery_bottom);
        canvas.drawRoundRect(batteryOutsideBorderRectF, outsideRound, outsideRound, batteryLinePaint);

        //电池电量
        power_left = battery_left + insideMargin;
        power_top = battery_top + insideMargin;
        power_right = power_left + powerWidth;
        power_bottom = power_top + powerHeight - insideMargin * 2;


        //当前分段数
        segmentCurrentCount = power / (100 / segmentNum);
        //剩余分段数
        segmentRemainingCount = segmentNum - segmentCurrentCount;
        //电池默认分成5份 ，中间4条间隔
        segmentWidth = (powerWidth - insideMargin * (segmentNum - 1)) / segmentNum;

        //画当前电量
        drawCurrentPower(canvas);

        //剩余电量
        drawRemainingPower(canvas);

        //画连接器
        drawPlug(canvas, battery_right);

        //画百分比
        drawTextScale(canvas);

        //画电池头
        drawBatteryHead(canvas, battery_right, battery_top);
    }


    /**
     * 画电池头部
     *
     * @param canvas        画布
     * @param battery_right 电池最右边
     * @param battery_top   电池最上边
     */
    private void drawBatteryHead(Canvas canvas, float battery_right, float battery_top) {

        float h_top = battery_top + powerHeight / 2 - batteryHeadHeight / 2;
        float h_right = battery_right + batteryHeadWidth;
        float h_bottom = h_top + batteryHeadHeight;
        RectF rectF3 = new RectF(battery_right, h_top, h_right, h_bottom);
        canvas.drawRoundRect(rectF3, outsideRound, outsideRound, batteryHeadPaint);
    }

    /**
     * 画半分比 文字
     *
     * @param canvas 画布
     */
    private void drawTextScale(Canvas canvas) {
        if (!isTextScaleEnabled)
            return;

        Paint.FontMetrics fontMetrics = batteryScaleTextPaint.getFontMetrics();
        float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
        float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom
        int baseLineY = (int) (batteryOutsideBorderRectF.centerY() - top / 2 - bottom / 2);//基线中间点的y轴计算公式
        canvas.drawText(TextUtils.isEmpty(text) ? power + "%" : text, batteryOutsideBorderRectF.centerX(), baseLineY, batteryScaleTextPaint);

    }

    /**
     * 画连接器
     *
     * @param canvas 画布
     */
    private void drawPlug(Canvas canvas, float battery_right) {

        if (plugged <= 0 || !isPlugEnabled)
            return;


        float i_right = battery_right + batteryHeadWidth + insideMargin;
        int bitmapWidth = pluggedBitmap.getWidth();
        int bitmapHeight = pluggedBitmap.getHeight();

        Rect srcRect = new Rect(0, 0, bitmapWidth, bitmapHeight);

        float destTop = power_top + (powerHeight / 2) - (bitmapHeight / 2f) - insideMargin;
        RectF destRect = new RectF(i_right, destTop, i_right + bitmapWidth, destTop + bitmapHeight);
        canvas.drawBitmap(pluggedBitmap, srcRect, destRect, batteryInsidePaint);
    }

    /**
     * 画剩余电量
     *
     * @param canvas 画布
     */
    private void drawRemainingPower(Canvas canvas) {
        if (power >= 100 || (plugged <= 0) || !isRemainingPowerEnabled)
            return;

        if (segmentRemainingCount <= 0)
            return;

        power_left = power_left - insideMargin;//初始化左边位置

        float power_current_width = segmentWidth * segmentCurrentCount + (insideMargin * (segmentCurrentCount + 1));

        float power_current_right = power_left + power_current_width;

        batteryRemainingPowerPaint.setAlpha(batteryRemainingAlpha);
        int average = 255 / segmentRemainingCount;
        for (int i = 0; i < segmentRemainingCount; i++) {

            //逐渐显示动画
            if (animationType == 1) {
                int segmentAverage = average * i;
                if (batteryRemainingAlpha >= segmentAverage) {
                    batteryRemainingPowerPaint.setAlpha(255);
                } else
                    batteryRemainingPowerPaint.setAlpha(0);
            }

            float segmentLeft = power_current_right + (insideMargin * i) + (i * segmentWidth);
            float segmentRight = power_current_right + (insideMargin * i) + (i + 1) * segmentWidth;
            segmentRectF.set(segmentLeft, power_top, segmentRight, power_bottom);
            canvas.drawRoundRect(segmentRectF, outsideRound, outsideRound, batteryRemainingPowerPaint);
        }
    }

    /**
     * 绘制当前电量
     *
     * @param canvas 画布
     */
    private void drawCurrentPower(Canvas canvas) {

        for (int i = 0; i < segmentCurrentCount; i++) {
            float segmentLeft = power_left + (insideMargin * i) + (i * segmentWidth);

            float segmentRight = power_left + (insideMargin * i) + (i + 1) * segmentWidth;

            segmentRectF.set(segmentLeft, power_top, segmentRight, power_bottom);
            canvas.drawRoundRect(segmentRectF, powerRound, powerRound, batteryInsidePaint);
        }
    }

    /**
     * 设置当前电量
     *
     * @param power 默认10
     */
    public void setPower(int power) {
        this.power = power;
        if (this.power < 0) {
            this.power = 0;
        }
        if (power < 100 && !remainingAlphaAnimator.isStarted())
            remainingAlphaAnimator.start();
        invalidate();
    }

    /**
     * 连接图标宽度
     *
     * @return 带有边距的
     */
    public int getPluggedWidth() {
        if (isPlugEnabled && pluggedBitmap != null)
            return (int) (pluggedBitmap.getWidth() + insideMargin * 2);

        return 0;
    }

    /**
     * usb 连接类型
     *
     * @param plugged 0
     */
    public void setPlugged(int plugged) {
        this.plugged = plugged;
        if (plugged == 1) {
            pluggedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.base_ic_socket);
        } else if (plugged == 2) {
            pluggedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.base_ic_usb);

        } else {
            pluggedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.base_ic_unkonwn);
        }
        invalidate();
    }


    /**
     * 当前电池电量 颜色
     *
     * @param batteryColor 默认 White
     */
    public void setBatteryColor(int batteryColor) {
        this.batteryColor = batteryColor;
    }

    /**
     * 边框颜色
     *
     * @param batteryLineColor 白色
     */
    public void setBatteryLineColor(int batteryLineColor) {
        this.batteryLineColor = batteryLineColor;
    }

    /**
     * 剩余电量颜色
     *
     * @param batteryRemainingColor 默认白色
     */
    public void setBatteryRemainingColor(int batteryRemainingColor) {
        this.batteryRemainingColor = batteryRemainingColor;
    }

    /**
     * 电池分段数量
     *
     * @param segmentNum 默认5段
     */
    public void setSegmentNum(int segmentNum) {
        this.segmentNum = segmentNum;
    }

    /**
     * 连接图标
     *
     * @param plugEnabled 默认 false
     */
    public void setPlugEnabled(boolean plugEnabled) {
        isPlugEnabled = plugEnabled;
    }

    /**
     * 电池文字
     *
     * @param textScaleEnabled 默认false
     */
    public void setTextScaleEnabled(boolean textScaleEnabled) {
        isTextScaleEnabled = textScaleEnabled;
    }

    public void setRemainingPowerEnabled(boolean remainingPowerEnabled) {
        isRemainingPowerEnabled = remainingPowerEnabled;
    }

    /**
     * 居中显示文字，
     *
     * @param text 电量百分比将会被覆盖
     */
    public void setText(String text) {
        this.text = text;
    }

    /**
     * 剩余电量动画类型
     *
     * @param animationType 默认1
     */
    public void setAnimationType(int animationType) {
        this.animationType = animationType;
    }

    /**
     * 设置动画时间
     *
     * @param duration 默认 3000ms
     */
    public void setDuration(int duration) {
        if (remainingAlphaAnimator.isRunning())
            remainingAlphaAnimator.cancel();
        this.duration = duration;
        remainingAlphaAnimator.setDuration(duration);
        remainingAlphaAnimator.start();
    }

    public int dp2px(float dp) {
        return (int) (dp * density + 0.5f);
    }
}

